/*
 * Dcm_UDS0x2E.c
 *
 *  Created on: 2018-1-16
 *      Author: Shute
 */
#include "UDS.h"


/****************************************************************
	     UDS:WriteDataByIdentifier (2E hex) service
 ***************************************************************/
#if(STD_ON == DCM_UDS_SERVICE0X2E_ENABLED)


static Std_ReturnType  DspInternalUDS0x2E_DidCheck(
        Dcm_OpStatusType OpStatus,
        uint16 RecDid,
        P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidCfgIndex,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)pDidCfgIndex,
        P2VAR(boolean, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidFlag,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);


static Std_ReturnType  DspInternalUDS0x2E_DidSesCheck(
        uint8 DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC) pNrc);


static Std_ReturnType  DspInternalUDS0x2E_DidSecCheck(
        uint8 DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);


static Std_ReturnType  DspInternalUDS0x2E_DidWriteDataLength(
        uint8   DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)pDidSize);


static Std_ReturnType  DspInternalUDS0x2E_DidWrite(
        Dcm_OpStatusType OpStatus,
        uint8 ProtocolCtrlId,
        uint8 MsgCtrlId,
        uint8 DidCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC) pNrc);


static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2EServiceConditionCheck(
        uint8 ProtocolCtrlId,
		P2VAR(uint8, AUTOMATIC, AUTOMATIC)MsgCtrlId);



static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsWriteDidSessionAndSecurityCheck(
        uint8   ProtocolCtrlId,
        uint8   DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)ErrorCode);
		
/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2E_DidCheck(
        Dcm_OpStatusType OpStatus,
        uint16 RecDid,
        P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidCfgIndex,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)pDidCfgIndex,
        P2VAR(boolean, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidFlag,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    Dcm_DidSupportedType    DidSupported;
	uint8     Index;
    uint8     Idx;
	boolean   Flag = FALSE;
    boolean   Flagx = FALSE;
	Std_ReturnType  ret = E_NOT_OK;

    *pRangeDidFlag = FALSE;
	/*find the corresponding DID in configuration*/
    /*first check whether the receiveDid is single did*/
	for (Index = 0; (Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
	{
        /*single did check*/
        if ((RecDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
        &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
        {
            Flag = TRUE;
            (*pDidCfgIndex) = Index;
            ret = E_OK;
        }
	}
    /*if the receiveDid is not single did,the check whether the receiveDid is range did*/
    if (FALSE == Flag)
    {
        /*range did check*/
        if ((RecDid < 0xF200u) || (RecDid > 0xF3FFu))
        {
            /*range did can not be DDDid*/
            for (Idx = 0; (Idx < Dcm_DspCfg.DcmDspDidRangeNum) && (FALSE == Flagx); Idx++)
            {
                /*this range not have gaps*/
                if ((RecDid >= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierLowerLimit)
                    &&(RecDid <= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierUpperLimit))
                {
                    if (TRUE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeHasGaps)
                    {
                        if (FALSE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeUsePort)
                        {
                            if (Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc
                                    != NULL_PTR)
                            {
                                ret = Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc(
                                        RecDid,
                                        OpStatus,
                                        &DidSupported);
                                if (ret == E_OK)
                                {
                                    if (DCM_DID_SUPPORTED == DidSupported)
                                    {
                                        *pRangeDidCfgIndex = Idx;
                                        *pRangeDidFlag = TRUE;
                                        Flagx = TRUE;
                                    }
                                    else
                                    {
                                        ret = E_NOT_OK;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        *pRangeDidCfgIndex = Idx;
                        *pRangeDidFlag = TRUE;
                        Flagx = TRUE;
                    }
                }
            }
        }

        if (TRUE == Flagx)
        {
            (*pDidCfgIndex) = Index;
            ret = E_OK;
        }
    }
	if (E_OK != ret)
	{
		/*if not found,send NRC 0x31*/
		(*pNrc) = DCM_E_REQUESTOUTOFRANGE;
	}

	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2E_DidSesCheck(
        uint8 DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC) pNrc)
{
	uint8    Index;
	boolean  Flag =FALSE;
	Std_ReturnType  ret = E_NOT_OK;
	P2CONST(Dcm_DspDidWriteType, AUTOMATIC, DCM_APPL_CONST) pDspDidWrite;

	/************************/
	pDspDidWrite = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidWrite;
	if ((NULL_PTR == pDspDidWrite))
	{
		/*Judge DID the configuration items pDcmDspDidWrite whether NULL_PTR,
		 *if not supported,send Nrc 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
         ret = E_NOT_OK;
	}
	else
	{
	    if (pDspDidWrite->DcmDspDidWriteSessionRefNum != 0u)
	    {
            for(Index = 0;
                    (Index < (pDspDidWrite->DcmDspDidWriteSessionRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSes
                        == pDspDidWrite->pDcmDspDidWriteSessionRow[Index])
                {
                    Flag = TRUE;
                    ret  = E_OK;
                }
            }
            if (FALSE == Flag)
            {
                /*if the current session is not supported,send NRC 0x7F*/
                (*pNrc) = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
                ret = E_NOT_OK;
            }
	    }
	}
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2E_DidSecCheck(
        uint8 DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    P2CONST(Dcm_DspDidWriteType, AUTOMATIC, DCM_APPL_CONST) pDspDidWrite;
    Std_ReturnType  ret;
	uint8    Index;
	uint8    SecNum;
	boolean  Flag =FALSE;

	/************************/
	pDspDidWrite = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidWrite;
	if ((NULL_PTR == pDspDidWrite))
	{
		/*Judge DID the configuration items pDcmDspDidWrite whether NULL_PTR,
		 *if not supported,send Nrc 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
		 ret = E_NOT_OK;
	}
	else
	{
        SecNum = pDspDidWrite->DcmDspDidWriteSecurityLevelRefNum;
        if (SecNum != 0u)
        {
            for (Index = 0;
                    (Index < (pDspDidWrite->DcmDspDidWriteSecurityLevelRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSec
                        == pDspDidWrite->pDcmDspDidWriteSecurityLevelRow[Index])
                {
                    Flag = TRUE;
                    ret = E_OK;
                }
            }
            if (FALSE == Flag)
            {
                /*if the current security is not supported,send NRC 0x33*/
                (*pNrc) = DCM_E_SECURITYACCESSDENIED;
                ret = E_NOT_OK;
            }
        }
        else
        {
            ret = E_OK;
        }
	}
	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif


/**************************************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2E_DidWriteDataLength(
        uint8   DidCfgIndex,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)pDidSize)
{
	uint8 DidSignalIndex;
	uint8 DidSignalNum;
	P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
	Std_ReturnType ret = E_OK;

	*pDidSize = 0;
	DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
	for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex++)
	{
		pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
		/*SWS_Dcm_00473*/
		if (pDspDidData->DcmDspDataType != DCM_UINT8_DYN)
		{
		    (*pDidSize) = (*pDidSize) + ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
		}
		else
		{
		    return E_NOT_OK;
		}
	}

	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2E_DidWrite(
        Dcm_OpStatusType OpStatus,
        uint8 ProtocolCtrlId,
        uint8 MsgCtrlId,
        uint8 DidCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC) pNrc)
{
	uint8 DidSignalIndex;
	uint8 DidSignalNum;
	uint16 DidSignalPos;
	uint16 Offest = 0;
	P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
	Std_ReturnType ret = E_OK;
#if(NVM_ENABLE == STD_ON)
	NvM_RequestResultType NvmRet;
#endif
	DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
	for (DidSignalIndex = 0; ((DidSignalIndex < DidSignalNum) && (ret == E_OK)); DidSignalIndex++)
	{
		pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
		DidSignalPos = Offest + ((Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
		        pDcmDspDidSignal[DidSignalIndex].DcmDspDidDataPos + 7u) >> 3u);
		if (pDspDidData->DcmDspDataWriteFnc == NULL_PTR)
		{
			/*if DcmDspDidWriteFnc is NULL,send NRC 0x22*/
			(void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_CONDITIONSNOTCORRECT);
			DsdInternal_ProcessingDone(ProtocolCtrlId);
			return(E_NOT_OK);
		}
		else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
		{
			if (pDspDidData->DcmDspDataType == DCM_UINT8_DYN)
			{
				ret = pDspDidData->DcmDspDataWriteFnc(
				        &Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u + DidSignalPos],
                        ((pDspDidData->DcmDspDataSize + 7u) >> 3u),
                        DCM_INVALID_UINT8,
                        pNrc);
			}
			else
			{
				ret = pDspDidData->DcmDspDataWriteFnc(
				        &Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u + DidSignalPos],
                        DCM_INVALID_UINT16,
                        DCM_INVALID_UINT8,
                        pNrc);
			}
		}
		else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
		{
			if (pDspDidData->DcmDspDataType == DCM_UINT8_DYN)
			{
				ret = pDspDidData->DcmDspDataWriteFnc(
				        &Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u + DidSignalPos],
                        ((pDspDidData->DcmDspDataSize + 7u) >> 3u),
                        OpStatus,
                        pNrc);
			}
			else
			{
				ret = pDspDidData->DcmDspDataWriteFnc(
				        &Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u + DidSignalPos],
                       DCM_INVALID_UINT16,
                       OpStatus,
                       pNrc);
			}
		}
		else
		{
			/*nothing*/
		}
		Offest += ((pDspDidData->DcmDspDataSize + 7u) >> 3u);

	    switch(ret)
	    {
	    	case E_OK:
	    		break;
	    	case DCM_E_PENDING:
	    		Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
	    	     break;
	    	case E_NOT_OK:
				 (void)DsdInternal_SetNrc(ProtocolCtrlId, *pNrc);
				 DsdInternal_ProcessingDone(ProtocolCtrlId);
                 break;
	    	default:
	 			 (void)DsdInternal_SetNrc(ProtocolCtrlId,
	 			         DCM_E_CONDITIONSNOTCORRECT);
				 DsdInternal_ProcessingDone(ProtocolCtrlId);
				 break;
	    }
#if(NVM_ENABLE == STD_ON)
		if ((USE_BLOCK_ID == pDspDidData->DcmDspDataUsePort) && (ret == E_OK))
		{
			NvM_SetBlockLockStatus(pDspDidData->DcmDspDataBlockId, FALSE);
			ret = NvM_WriteBlock(pDspDidData->DcmDspDataBlockId,
			        &Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u + DidSignalPos]);
			if (E_NOT_OK == ret)
			{
				return (E_NOT_OK);
			}
			ret = NvM_GetErrorStatus(pDspDidData->DcmDspDataBlockId, &NvmRet);
			if (E_OK == ret)
			{
				if (NVM_REQ_OK == NvmRet)
				{
					NvM_SetBlockLockStatus(pDspDidData->DcmDspDataBlockId, TRUE);
					ret = E_OK;
				}
				else
				{
					(void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_GENERALREJECT);
					DsdInternal_ProcessingDone(ProtocolCtrlId);
					return(E_NOT_OK);
				}
			}
		}
		else
		{

		}
#endif
	}

	return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2EServiceConditionCheck(
        uint8 ProtocolCtrlId,
		P2VAR(uint8, AUTOMATIC, AUTOMATIC)MsgCtrlId)
{
	Std_ReturnType ret;

	/*************************************************/
	/*if the required protocol is configured,
	 * get the index of runtime datum*/
	*MsgCtrlId = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;

	/*************************************************/
	#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
	/*session check,check whether the current
	 * session supports the request service*/
	ret = DsdInternal_SesCheck(ProtocolCtrlId,
	        SID_WRITE_DATA_BY_IDENTIFIER);
	if(E_NOT_OK == ret)
	{
		/****@req DCM-FUNR-073[DCM211]****/
		/*the current session does not support the
		 *  request service,send NRC = 0x7F*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,
		        DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
	}
	#endif

	/*************************************************/
	#if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
	/*security check,check whether the current
	 * security supports the request service*/
	ret = DsdInternal_SecurityCheck(ProtocolCtrlId,
	        SID_WRITE_DATA_BY_IDENTIFIER);
	if (E_NOT_OK == ret)
	{
		/****@req DCM-FUNR-074[DCM217]****/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,
		        DCM_E_SECURITYACCESSDENIED); /*NRC = 0x33*/
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
	}
	#endif
    /*check the massage length*/
    if (Dcm_MsgCtrl[*MsgCtrlId].MsgContext.ReqDataLen
            < DCM_UDS0X2E_REQ_DATA_MINLENGTH)
    {
        /*the length of massage is not correct,send NRC 0x13*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }

	return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsWriteDidSessionAndSecurityCheck(
        uint8   ProtocolCtrlId,
        uint8   DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)ErrorCode)
{
	Std_ReturnType ret;

	/*check the current session*/
	#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
	ret = DspInternalUDS0x2E_DidSesCheck(DidInfoCfgIndex, ErrorCode);
	if(E_NOT_OK == ret)
	{
		/*if the current session is not support the Did,send NRC*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId, *ErrorCode);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return  E_NOT_OK;

	}
	#endif
    /**************************************************/
	/*check the current security level*/
	#if(STD_ON==DCM_SECURITY_FUNC_ENABLED)
	ret = DspInternalUDS0x2E_DidSecCheck(DidInfoCfgIndex, ErrorCode);
	if(E_NOT_OK == ret)
	{
		/*if the current security is not support the DID,send NRC*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId, *ErrorCode);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return  E_NOT_OK;
	}
	#endif

	return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)Dcm_UDS0x2E(
		Dcm_OpStatusType OpStatus,
		uint8  ProtocolCtrlId,
		P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
    uint16    RecDid;
    uint16    DidSize = 0;
    uint16    Offset;
	uint8     DidCfgIndex;
	uint8     DidInfoCfgIndex;
	uint8     TxChannelCtrlIndex;
	uint8     TxChannelCfgIndex;
	uint8     RangeDidCfgIndex;
	boolean   RangeDidFlag;
#endif
    uint8     MsgCtrlId;
	Std_ReturnType ret;

	/*************************************************/
	ret = Dcm_Uds0x2EServiceConditionCheck(ProtocolCtrlId, &MsgCtrlId);
	if(E_OK != ret)
	{
		return ret;
	}

#if (STD_OFF == DCM_DSP_DID_FUNC_ENABLED)
	/*NRC 0x31:request out of range*/
	(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
	DsdInternal_ProcessingDone(ProtocolCtrlId);
	return E_NOT_OK;

#else
    /**************************************************/
	/*get the required DID from request message*/
	RecDid = (uint16)((uint16)((uint16)Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[1]) << 8u)\
		    |((uint16) Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2]);

	/*Determine if the DID is configured*/
	ret = DspInternalUDS0x2E_DidCheck(
	         OpStatus,
	         RecDid,
	         &RangeDidCfgIndex,
             &DidCfgIndex,
             &RangeDidFlag,
             ErrorCode);
	if(E_NOT_OK == ret)
	{
		/*if not found,send NRC 0x31*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return  E_NOT_OK;
	}
    else if (DCM_E_PENDING == ret)
    {
        Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
        return ret;
    }
    else
    {}

    /**************************************************/
    if (TRUE == RangeDidFlag)
    {
        DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
                DcmDspDidRangeInfoIndex;
    }
    else
    {
        DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidInfoIndex;
    }

    /*check whether the Did can be configured*/
	if ((TRUE == (Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].DcmDspDidDynamicallyDefined))
		||(Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidWrite == NULL_PTR))
	{
		/*if the Did can be dynamically defined,send NRC 0x31*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return  E_NOT_OK;
	}

    /**************************************************/
	ret = Dcm_UdsWriteDidSessionAndSecurityCheck(	ProtocolCtrlId,
													DidInfoCfgIndex,
													ErrorCode	);
	if(E_OK != ret)
	{
		return ret;
	}

    /**************************************************/
    if (FALSE == RangeDidFlag)
    {
        ret = DspInternalUDS0x2E_DidWriteDataLength(DidCfgIndex,
                                                    &DidSize);
        if(E_OK == ret)
        {
            /*check message length*/
           if((3u+DidSize )!= (uint16)Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen)
           {
                /*if the message length is not correct,send NRC 0x13*/
                (void)DsdInternal_SetNrc(ProtocolCtrlId,
                        DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
                DsdInternal_ProcessingDone(ProtocolCtrlId);
                return E_NOT_OK;
           }
        }

       /**************************************************/
        ret = DspInternalUDS0x2E_DidWrite( OpStatus,
                                           ProtocolCtrlId,
                                           MsgCtrlId,
                                           DidCfgIndex,
                                           ErrorCode);
        if(E_OK != ret)
        {
            return ret;
        }
    }
    else
    {
        /*read data length to be writen*/
        if (NULL_PTR == Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
                DcmDspDidRangeReadDataLengthFnc)
        {
            /*DcmDspDidReadDataLengthFnc is NULL,send NRC 0x22*/
            (*ErrorCode) = DCM_E_CONDITIONSNOTCORRECT;
            return E_NOT_OK;
        }
        ret = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
                DcmDspDidRangeReadDataLengthFnc(RecDid, OpStatus, &DidSize);
        if(E_NOT_OK == ret)
        {
           (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
           DsdInternal_ProcessingDone(ProtocolCtrlId);
           return  E_NOT_OK;
        }
        else if (DCM_E_PENDING == ret)
        {
            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
            return ret;
        }
        else
        {}

        /*write data*/
       if (NULL_PTR == Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
               DcmDspDidRangeWriteDidFnc)
       {
           (void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_CONDITIONSNOTCORRECT);
           DsdInternal_ProcessingDone(ProtocolCtrlId);
           return E_NOT_OK;
       }

       ret = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].DcmDspDidRangeWriteDidFnc(
               RecDid,
               &(Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3]),
               OpStatus,
               DidSize,
               ErrorCode);
       if(E_NOT_OK == ret)
       {
          (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
          DsdInternal_ProcessingDone(ProtocolCtrlId);
          return  E_NOT_OK;
       }
       else if (DCM_E_PENDING == ret)
       {
           Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
           return ret;
       }
       else
       {}
    }

	/*assemble and send positive response*/
	SchM_Enter_Dcm(Dcm_MsgCtrl);
	TxChannelCtrlIndex = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
	TxChannelCfgIndex = Dcm_ChannelCtrl[TxChannelCtrlIndex].Dcm_ChannelCfgIndex;
	Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCfgIndex].offset;
    /* check tx data length */
    if((3u) > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
    {
        /*Pdu length is bigger than buffer size,ignore the request message */
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_RESPONSETOOLONG);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
	Dcm_Channel[Offset] = 0x6E;
	Dcm_Channel[Offset + 1u] = (uint8)(RecDid>>8u);
	Dcm_Channel[Offset + 2u] = (uint8)RecDid;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen = 3u;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen    = 3u;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData      = &Dcm_Channel[Offset];
	SchM_Exit_Dcm(Dcm_MsgCtrl);
	DsdInternal_ProcessingDone(ProtocolCtrlId);
#endif
	return  E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
